/*
 * 動的にライブラリをロードするルーチン用に dlfcn.h が必要
 */
#include <dlfcn.h>

#include <stdlib.h>
#include <stdio.h>

/*
 * "libhello.h" をインクルードする必要がないことに注意して
 * ください。但し、関連情報を指定する必要があります。
 * dlsym() で取得する値を保持するための型が必要です。
 */

/*
 * "simple_demo_function" 型は、引数を取らず、何も値を返さない
 * 関数を示しています。
 */

typedef void (*simple_demo_function)(void);

int main(void) {
    const char *error;
    void *module;
    simple_demo_function demo_function;

    /* 動的ライブラリをロードする */
    module = dlopen("libhello.so", RTLD_LAZY);
    if (!module) {
        fprintf(stderr, "libhello.so をオープンできませんでした: %s\n", dlerror());
        exit(1);
    }

    /* シンボルを取得する */
    dlerror();
    demo_function = dlsym(module, "hello");
    if ((error = dlerror())) {
        fprintf(stderr, "hello が見つかりませんでした: %s\n", error);
        exit(1);
    }

    /* 動的ライブラリ内の関数を呼び出す */
    (*demo_function)();

    /* 全て終了。きちんとクローズする */
    dlclose(module);

    return 0;
}
